package com.bdqn.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bdqn.mapper.RightMapper;
import com.bdqn.mapper.RoleMapper;
import com.bdqn.pojo.Right;
import com.bdqn.pojo.Role;
import com.bdqn.pojo.User;
import com.bdqn.service.RoleService;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.BeansException;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class RoleServiceImpl implements RoleService {
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RightMapper rightMapper;


    @Override
    public List<Role> list() {
        return roleMapper.list();
    }

    @Override
    public List<Role> findAllRoles() {
        return roleMapper.findAllRoles();
    }

    @Override
    public Role saveRole(Role role) {
        return roleMapper.saveRole(role);
    }

    @Override
    public void deleteRoleById(Long roleId) {
        roleMapper.deleteRoleById(roleId);
    }

    @Override
    public Role getRole(Long roleId) {
        return roleMapper.getRole(roleId);
    }

    @Override
    public Page<Role> findRolesByRoleNameLike(String roleName, Pageable pageable) {
        return roleMapper.findRolesByRoleNameLike("%"+roleName+"%",pageable);
    }




    @Override
    public List<Right> findAllRights() {
        return roleMapper.findAllRights();
    }

    @Override
    public List<Right> findRightsByRole(Role role) {
        return rightMapper.findRightsByRolesOrderByRightCode(role);
    }

    @Override
    public Role findRoleByUsers(User user) {
        return roleMapper.findRoleByUsers(user);
    }

    @Override
    public void reloadFilterChainDefinitions() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ServletContext servletContext=request.getSession().getServletContext();
            AbstractShiroFilter shiroFilter = (AbstractShiroFilter) WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).getBean("shiroFilter");
            synchronized (shiroFilter) {
                //获取过滤管理器
                PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
                DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
                manager.getFilterChains().clear();
                Map<String,String> chains =loadFilterChainDefinitions();
                for(Map.Entry<String,String> entry:chains.entrySet()){
                    String url=entry.getKey();
                    String chainDefinition=entry.getValue().trim().replace(" ", "");
                    manager.createChain(url,chainDefinition);
                }
                System.out.println("权限更新成功");
            }
        } catch (BeansException e) {
           e.printStackTrace();
        } catch (IllegalStateException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Map<String, String> loadFilterChainDefinitions() {
       Map<String,String> filterChainDefinitionMap=new LinkedHashMap<String,String>();
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/fonts/**","anon");
        filterChainDefinitionMap.put("/images/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/localcss/**","anon");
        filterChainDefinitionMap.put("/localjs/**","anon");
        filterChainDefinitionMap.put("/login","anon");
        filterChainDefinitionMap.put("/logout","logout");
        List<Right> rights=findAllRights();
        for(Right right:rights){
            if(right.getRightUrl()!=null && !right.getRightUrl().trim().equals("")){
                filterChainDefinitionMap.put(right.getRightUrl(),"perms["+right.getRightCode()+"]");
            }
            filterChainDefinitionMap.put("/**","authc");
        return filterChainDefinitionMap;
        }
        return null;
    }
}
